package graphicsExtended;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import myAnnotations.Constant;

/**
 *
 * Fully Tested: No
 * Fully Documented: No
 * Created: 21-Apr-2012
 * Last Updated: 21-Apr-2012
 *
 * @author Shimu Wu
 */
public class Graphics2DExtended {

    private Graphics2DExtended() {
    }

    public static void drawLine(Graphics2D graphics, int screenHeight,
            Point2D p1, Point2D p2) {
        graphics.drawLine((int) p1.getX(), screenHeight - (int) p1.getY(),
                (int) p2.getX(), screenHeight - (int) p2.getY());
    }

    public static void drawCircle(Graphics2D graphics, int screenHeight,
            Point2D center, double radius) {
        Ellipse2D ellipse = new Ellipse2D.Double(center.getX() - radius,
                screenHeight - (center.getY() - radius), radius * 2,
                radius * 2);

        graphics.fill(ellipse);
    }

    /**
     * Returns a copy of the area in the given img whose top left corner is 
     * at (x, y) and has the given width and height.
     * @param img
     * @param x
     * @param y
     * @param width
     * @param height
     * @return 
     */
    public static BufferedImage snip(BufferedImage img,
            int x, int y, int width, int height) {
        return Graphics2DExtended.copyImage(
                img.getSubimage(x, y, width, height));
    }

    /**
     * Returns a copy of the given img.
     * 
     * @param img
     * @return 
     */
    public static BufferedImage copyImage(Image img) {
        int width = img.getWidth(null);
        int height = img.getHeight(null);
        BufferedImage copy = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = copy.createGraphics();
        g.drawImage(img, 0, 0, null);
        return copy;
    }

    /**
     * Layer (draw on top of each other) the images given. 
     * @param images
     * @return 
     */
    @Constant
    public static BufferedImage layer(Image... images) {
        int maxWidth = 0;
        int maxHeight = 0;
        for (Image img : images) {
            maxWidth = Math.max(maxWidth, img.getWidth(null));
            maxHeight = Math.max(maxHeight, img.getHeight(null));
        }
        return layer(maxWidth, maxHeight, images);
    }

    /**
     * Layer (draw on top of each other) the images given. The first image
     * in the list will be drawn first (hence images that are at the back
     * of the layer should be listed first, images that are in front in the 
     * layer should be listed last). Example, if one wants to draw img1, img2,
     * img3, where img1 is the background, img2 is an object, img3 is another
     * object that is closer to the viewer than the first object, then
     * one should call layer as layer(width, height, img1, img2, img3);
     * 
     * @param width
     * @param height
     * @param images
     * @return 
     */
    @Constant
    public static BufferedImage layer(int width, int height, Image... images) {
        BufferedImage layer = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = layer.createGraphics();
        for (Image img : images) {
            g.drawImage(img, 0, 0, null);
        }
        return layer;
    }

    /**
     * Fills the given img with a box with the given width and height 
     * that has the given color and alpha value from the given (x, y) 
     * as the top left hand corner 
     * @param img
     * @param x
     * @param y
     * @param width
     * @param height
     * @param color
     * @param alpha 
     */
    public static void clear(BufferedImage img, int x, int y, 
            int width, int height) {
        Graphics2D g = img.createGraphics();
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR));
        g.fillRect(x, y, width, height);
    }
    
    public static void clear(BufferedImage img) {
        clear(img, 0, 0, img.getWidth(), img.getHeight());
    }
}
